package me.liuhui.mall.manager.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import me.liuhui.mall.manager.exception.ServiceException;
import me.liuhui.mall.manager.service.AdminTokenService;
import me.liuhui.mall.manager.service.security.CurrentAdmin;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class AdminTokenServiceImpl implements AdminTokenService {
    @Value("${token.secret:mini-manager}")
    private String tokenSecret;
    @Value("${token.expire:30}")
    private int tokenExpire;

    @Override
    public String createToken(CurrentAdmin admin) {
        Map<String, Object> payload = new HashMap<>(4);
        payload.put("userName", admin.getUsername());
        payload.put("name", admin.getRealName());
        payload.put("id", admin.getAdminId());
        payload.put("loginTime", new Date());
        payload.put("ip", ServletUtil.getClientIP(((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()));
        DateTime now = DateTime.now();
        DateTime newTime = now.offsetNew(DateField.DAY_OF_MONTH, tokenExpire);
        //签发时间
        payload.put(JWTPayload.ISSUED_AT, now);
        //过期时间
        payload.put(JWTPayload.EXPIRES_AT, newTime);
        //生效时间
        payload.put(JWTPayload.NOT_BEFORE, now);
        return TOKEN_PREFIX + JWTUtil.createToken(payload, tokenSecret.getBytes());
    }

    @Override
    public String getUsernameFromToken(String token) {
        if (token == null || !token.startsWith(TOKEN_PREFIX)) {
            throw new ServiceException("token格式错误");
        }
        token = token.replaceFirst(TOKEN_PREFIX, "");
        JWT jwt = JWTUtil.parseToken(token);
        if (!jwt.setKey(tokenSecret.getBytes()).verify()) {
            throw new ServiceException("token验证失败");
        }
        if (!jwt.validate(0)) {
            throw new ServiceException("token已过期，请重新登录");
        }
        return String.valueOf(jwt.getPayload("userName"));
    }
}
